<template>
	<view class="upload-img">
		<view class="file-item" v-for="(item, index) in files" :key="index">
			<view class="close-btn" @click="handleDelete(index)">
				<view class="iconfont icon-close"></view>
			</view>
			<view class="img-box" @click="handlePreviewImage(index)">
				<image v-if="!item.uploaded" :src="item.path" mode="aspectFill"></image>
				<image v-else :src="item.url" mode="aspectFill"></image>
			</view>
			<view v-if="item.upload" class="upload-progress">
				<view class="loading"></view>
				<view class="progress">{{ item.progress }}%</view>
			</view>
		</view>
		<view v-if="(!files.length || multiple) && files.length < max" class="upload-btn" @click="handleUpload">
			<view class="btn-box">
				<text class="iconfont icon-add"></text>
			</view>
		</view>
	</view>
</template>

<script>
	import Setting from '@/setting.js'
	import {
		previewImage
	} from '@/utils/uploadImg.js'
	import { uuid } from '@/libs/common.js'

	export default {
		name: "upload-img",
		props: {
			multiple: {
				type: Boolean,
				default: false
			},
			value: {
				type: Array,
				default: () => []
			},
			max: {
				type: Number,
				default: 999
			},
			name: {
				type: String,
				default: 'file',
			},
			module: {
				type: String,
				default: 'file',
			}
		},
		data() {
			return {
				files: [],
				imgUrl: Setting.imgUrl,
				uploadUrl: Setting.apiBaseURL + '/apiapp/v1/tencent/cos_auth', // 上传地址
			};
		},
		watch: {
			value: {
				handler(newVal) {
					this.files = newVal.map(item=> {
						return {
							...item,
							upload: item.upload || false, // 是否上传中
							progress: 100, // 上传进度
							error: item.error || false, // 是否上传失败
							errMsg: item.errMsg || '', // 错误信息
							uploaded: item.uploaded || true, // 是否已上传
							uuid: item.uuid || uuid(6),
						}
					})
				},
				immediate: true
			}
		},
		methods: {
			// 预览图片
			handlePreviewImage(index) {
				previewImage([this.files[index].url], index)
			},
			// 删除图片
			handleDelete(index) {
				this.files = this.files.filter((item, idx) => {
					return index !== idx
				})
				this.$emit('remove', {
					index,
					files: this.files
				})
			},
			// 上传图片
			handleUpload() {
				let count = this.max;
				if (!this.multiple) {
					count = 1;
				}
				uni.chooseImage({
					count: count, // 默认9
					sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图，默认二者都有
					sourceType: ['album', 'camera'], // 从相册选择
					success: (res) => {
						const files = res.tempFiles.map(item => ({
							path:  item.path, // 图片路径
							url: '', // 图片路径
							name: item.name ? item.name : new Date().getTime() + item.path.substring(item.path.lastIndexOf('.'), item.path.length), // 图片名称
							size: item.size, // 图片大小
							type: item.type, // 图片类型
							upload: false, // 是否上传中
							progress: 0, // 上传进度
							error: false, // 是否上传失败
							errMsg: '', // 错误信息
							uploaded: false, // 是否已上传
							uuid: uuid(6),
						}))
						this.files = [...this.files, ...files]
						this.startUpload(files)
					}
				});
			},
			// 开始上传
			startUpload(files) {
				const promises = []
				for (let i = 0; i < files.length; i++) {
					const item = files[i]
					if (item.upload || item.uploaded) continue
					item.uuid = this.uploadFile(item)
					promises.push(item.uuid)
				}
				Promise.all(promises).then((posts)=> {
					console.log('files', this.files);
					this.$emit('success', this.files)
				}).catch((reason)=> {
					console.log('出错了', reason)
				});
			},
			uploadFile(file) {
				const suffixIndex = file.path.lastIndexOf('.')
				return new Promise(async (resolve, rejects) => {
					file.upload = true
					const params = {
						file_name: file.name,
						file_module: this.module
					}
					const res_cos = await this.$api.cosAuthApi(params)
					const uploadTask = uni.uploadFile({
						url: res_cos.url,
						filePath: file.path,
						name: this.name,
						header: {
							'access_token': this.$store.state.login.token
						},
						formData : res_cos.data,
						success: (uploadFileRes) => {
							if (uploadFileRes.statusCode) {
								file.url = res_cos.src
								// file.path = res_cos.src
								file.uploaded = true // 已上传
							} else {
								file.error = true // 上传失败
								file.errMsg = uploadFileRes.data // 错误信息
							}
						},
						fail: (err) => {
							file.error = true // 上传失败
							file.errMsg = err.message // 错误信息
						},
						complete: () => {
							file.upload = false // 上传完成
							resolve()
						}
					})

					uploadTask.onProgressUpdate((res) => {
						// console.log(' ');
						// console.log('上传进度' + res.progress);
						// console.log('已经上传的数据长度' + res.totalBytesSent);
						// console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);

						file.progress = res.progress
						this.$forceUpdate()

						// 测试条件，取消上传任务。
						// if (res.progress > 50) {
						// uploadTask.abort();
						// }
					});
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	.upload-img {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		gap: 16rpx;

		.files {
			display: flex;
			flex-wrap: wrap;
			align-items: center;
			gap: 20rpx;
			flex: 1;
			flex-shrink: 0;
		}

		.upload-btn,
		.file-item {
			position: relative;
			width: 160rpx;
			height: 160rpx;
			display: flex;
			align-items: center;
			border-radius: 12rpx;
			justify-content: center;
			background-color: #F3F3F3;
		}

		.upload-btn {

			.btn-box {
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				width: 100%;
				height: 100%;
				flex-direction: column;
				gap: 8rpx;

				display: flex;
				align-items: center;
				justify-content: center;
			}

			.iconfont {
				font-size: 30rpx;
				color: rgba(0, 0, 0, 0.4);
			}

			.upload-label {
				font-size: 28rpx;
				font-weight: 400;
				line-height: 44rpx;
				text-align: left;
				color: rgba(0, 0, 0, 0.7);
			}
		}

		.file-item {
			border-radius: 12rpx;
			// border: 1px dashed #DCDCDC;

			.img-box {
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				width: 100%;
				height: 100%;
				// overflow: hidden;
				border-radius: 12rpx;
				vertical-align: bottom;

				display: flex;
				align-items: center;
				justify-content: center;
			}

			image {
				width: 100%;
				height: 100%;
				border-radius: 12rpx;
			}

			.close-btn {
				position: absolute;
				top: 0;
				right: 0;
				z-index: 99;
				padding: 8rpx;
				display: flex;
				align-items: center;
				box-sizing: border-box;
				justify-content: center;
				border-radius: 0 12rpx 0 12rpx;
				background-color: rgba(0, 0, 0, 0.4);
			}

			.icon-close {
				color: #FFFFFF;
				font-size: 16rpx;
				line-height: 1;
			}

			.upload-progress {
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				width: 100%;
				height: 100%;
				border-radius: inherit;
				background-color: rgba(0, 0, 0, 0.4);

				display: flex;
				align-items: center;
				flex-direction: column;
				justify-content: center;

				.loading {
					width: 46rpx;
					height: 46rpx;
					border-radius: 100%;
					border: 2px solid #FFF;
					border-top-color: transparent;
					animation: circle infinite 0.75s linear;
				}

				.progress {
					font-size: 24rpx;
					font-weight: 400;
					line-height: 40rpx;
					text-align: left;
					color: #FFFFFF;
					padding-top: 8rpx;
				}

				// 转转转动画
				@keyframes circle {
					0% {
						transform: rotate(0);
					}

					100% {
						transform: rotate(360deg);
					}
				}
			}
		}
	}
</style>